// Copyright Gary Evans 2006-2007.

using System;
using System.Collections.Generic;
using System.Text;

using NUnit.Framework;

using Taumuon.Jabuka.Physics.Collision;

namespace Taumuon.Jabuka.Physics.Test
{
	/// <summary>
	/// Tests the collision response of two spheres
	///  where the collisions are not directly along the
	///  line connecting the spheres' centres.
	///  The collisions are totally elastic, between
	///   rigid bodies.
	/// </summary>
	[TestFixture]
	public class TestSphereCollisionResponse
    {
        #region Tests

        /// <summary>
        /// Tests the collision response of two identical spheres
        ///  moving towards each other in the x direction with mirrored velocities,
        ///  and moving in the y direction with identical velocity component.
        /// </summary>
        [Test]
        public void TestCollisionIdenticalSpheresTravellingInYDirection()
        {
            Sphere sphere1 = CreateSphere(1.0, new Vector(1.0, 1.0, 0.0),
                new Vector(0.0, 0.0, 0.0), 1.0);
            Sphere sphere2 = CreateSphere(1.0, new Vector(-1.0, 1.0, 0.0),
                new Vector(2.0, 0.0, 0.0), 1.0);
            CollisionManager.DoCollisionResponse(sphere1, sphere2);
            Assert.IsTrue(TestVector.AreVectorValuesCorrect(
                sphere1.EulerRigidBody.Velocity, -1.0, 1.0, 0.0));
            Assert.IsTrue(TestVector.AreVectorValuesCorrect(
                sphere2.EulerRigidBody.Velocity, 1.0, 1.0, 0.0));
        }

		/// <summary>
		/// Tests the collision response of two identical spheres
		///  moving towards each other in the y direction with mirrored velocities,
		///  and moving in the x direction with identical velocity component.
		/// </summary>
		[Test]
		public void TestCollisionIdenticalSpheresTravellingInXDirection()
		{
			Sphere sphere1 = CreateSphere(1.0, new Vector(1.0, 1.0, 0.0),
				new Vector(0.0, 0.0, 0.0), 1.0);
			Sphere sphere2 = CreateSphere(1.0, new Vector(1.0, -1.0, 0.0),
				new Vector(0.0, 2.0, 0.0), 1.0);
			CollisionManager.DoCollisionResponse(sphere1, sphere2);
			Assert.IsTrue(TestVector.AreVectorValuesCorrect(
				sphere1.EulerRigidBody.Velocity, 1.0, -1.0, 0.0));
			Assert.IsTrue(TestVector.AreVectorValuesCorrect(
				sphere2.EulerRigidBody.Velocity, 1.0, 1.0, 0.0));
		}

        #endregion Tests

        #region Helper Methods

        /// <summary>
        /// A helper method to create a sphere.
        /// </summary>
        /// <returns></returns>
        private Sphere CreateSphere(double mass, Vector initialVelocity,
            Vector initialLocation, double radius)
        {
            EulerRigidBody body = new EulerRigidBody(initialLocation,
                initialVelocity, mass);
            return new Sphere(body, radius);
        }

        #endregion Helper Methods

        private const double Tolerance = 1e-10;
	}
}
